#include <stdio.h>
#include <stdint.h>

#define MAX_MODBUS_ITEM 12
#define MAX_REGISTER_NUM 20

typedef struct
{
    uint16_t slave_id;
    uint16_t cmd;
    uint16_t poll_time;
    uint16_t register_addr;
    uint16_t register_num;
    uint16_t event_trigger;
    uint16_t poll_delay;
    uint16_t lost;
} ST_MODBUS_ITEM;

typedef struct
{
    uint16_t modbus_addr;
    ST_MODBUS_ITEM item[MAX_MODBUS_ITEM];
} ST_MODBUS_COMPONENT;

// 全局变量用于保存有效数据
uint16_t global_data[MAX_MODBUS_ITEM][MAX_REGISTER_NUM];

// 模拟 CRC 计算函数
uint16_t calculate_crc(uint8_t *data, uint16_t length)
{
    // 实现您的 CRC 计算逻辑
    // 返回计算得到的 CRC 校验值
    return 0;
}

// 解析 Modbus Slave 回复数据的函数
void parse_modbus_reply(uint8_t *reply_data, uint16_t reply_length)
{
    // 验证本地地址和 CRC 的正确性
    uint16_t slave_addr = reply_data[0];
    if (slave_addr != 1)
    { // 假设本地地址为1
        printf("Invalid slave address!\n");
        return;
    }

    // 检查 CRC 校验值
    uint16_t received_crc = (reply_data[reply_length - 1] << 8) | reply_data[reply_length - 2];
    uint16_t calculated_crc = calculate_crc(reply_data, reply_length - 2);
    if (received_crc != calculated_crc)
    {
        printf("Invalid CRC!\n");
        return;
    }

    // 解析有效数据
    uint16_t register_data_length = reply_data[2] - 1;
    uint16_t register_data_start = 3;

    for (int i = 0; i < MAX_MODBUS_ITEM; i++)
    {
        uint16_t register_num = global_data[i][0];
        if (register_num == 0)
        {
            // 当前 item 配置为空，跳过
            continue;
        }

        if (register_data_start + register_num * 2 > reply_length)
        {
            // 有效数据长度不足，跳过
            continue;
        }

        // 解析并保存有效数据
        for (int j = 0; j < register_num; j++)
        {
            uint16_t register_value = (reply_data[register_data_start + j * 2] << 8) | reply_data[register_data_start + j * 2 + 1];
            global_data[i][j + 1] = register_value;
        }

        // 更新下一个 item 的数据起始位置
        register_data_start += register_num * 2;
    }
}

int main()
{
    // 模拟收到的 Modbus Slave 回复数据
    uint8_t reply_data[] = {1, 3, 8, 0, 10, 0, 20, 0, 30, 0, 40, 0, 50, 0, 60, 0, 70, 0, 80, 0, 0x3A, 0x99};
    uint16_t reply_length = sizeof(reply_data) / sizeof(reply_data[0]);

    // 解析 Modbus Slave 回复数据
    parse_modbus_reply(reply_data, reply_length);

    // 打印保存的有效数据
    for (int i = 0; i < MAX_MODBUS_ITEM; i++)
    {
        uint16_t register_num = global_data[i][0];
        if (register_num == 0)
        {
            // 当前 item 配置为空，跳过
            continue;
        }

        printf("Item %d:\n", i + 1);
        printf("Register Num: %d\n", register_num);

        for (int j = 0; j < register_num; j++)
        {
            uint16_t register_value = global_data[i][j + 1];
            printf("Register %d: %d\n", j + 1, register_value);
        }

        printf("\n");
    }

    return 0;
}